﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cocon90.Lib.Dal.Store
{
    /// <summary>
    /// 表示一个可以编辑的BaseStore，继承自BaseStore
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class EditableStore<T> : BaseStore<T> where T : class,Rule.IModel, new()
    {
        public EditableStore()
        {
            base.OnDataChanged += EditableStore_OnDataChanged;
            DataLoaded = new List<T>();
        }

        void EditableStore_OnDataChanged(object data, object staticData, int pageNumber, int pageSize, int staticPageNumber, int staticPageSize)
        {
            InitDataLoaded();

        }
        /// <summary>
        /// 初始化加载列
        /// </summary>
        private void InitDataLoaded()
        {
            if (Data == null) return;
            DataLoaded = new List<T>();
            foreach (var item in Data)
            {
                var obj = (T)Activator.CreateInstance(typeof(T));
                foreach (var prop in typeof(T).GetProperties())
                {
                    if (prop.GetSetMethod() != null)
                        prop.SetValue(obj, prop.GetValue(item, null), null);
                }
                DataLoaded.Add(obj);
            }
        }

        /// <summary>
        /// 刚刚加载加来的数据（未发生过任何更改）
        /// </summary>
        public List<T> DataLoaded { get; set; }
        List<Rule.EditedEntry<T>> dataEdited;
        /// <summary>
        ///获取 编辑过的数据（发生更改之后的数据） 
        /// </summary>
        public List<Rule.EditedEntry<T>> GetChanged()
        {
            var db = DataHelperFactory.CreateInstence();
            var mh = new Tools.ModelHelper<T>();
            if (dataEdited == null)
                dataEdited = new List<Rule.EditedEntry<T>>();
            dataEdited.Clear();
            var type = typeof(T);
            var model = (T)Activator.CreateInstance(type);
            var primeryKeyProprty = type.GetProperty(db.getString(Tools.sqlHelper.getPrimeryKey(model.TableName)));
            List<Rule.EditedEntry<T>> lst = new List<Rule.EditedEntry<T>>();

            for (int i = 0; i < DataLoaded.Count; i++)
            {
                var editedModel = new Rule.EditedEntry<T>();
                //判断是否没有发生过更改
                if (mh.IsModelEqual(DataLoaded[i], Data[i])) { continue; }
                //如果发生过了更改
                var newData = base.Data[i];//取得现在的数据库中对应行模型
                var oldData = DataLoaded[i];
                editedModel.NewDataModel = newData;
                editedModel.OldDataModel = oldData;
                Dictionary<string, object> propNewValue = new Dictionary<string, object>();
                Dictionary<string, object> propOldValue = new Dictionary<string, object>();
                foreach (var prop in type.GetProperties())
                {
                    var newValue = prop.GetValue(newData, null);
                    var oldValue = prop.GetValue(oldData, null);
                    if (newValue + "" == oldValue + "") continue;
                    propNewValue.Add(prop.Name, newValue);
                    propOldValue.Add(prop.Name, oldValue);
                }
                editedModel.ChangedPropertyNewValue = propNewValue;
                editedModel.ChangedPropertyOldValue = propOldValue;
                dataEdited.Add(editedModel);
            }
            return dataEdited;
        }
        /// <summary>
        /// 将发生的更新应用到数据库
        /// </summary>
        /// <returns></returns>
        public Rule.EffectEntry ApplyChange()
        {

            var changes = GetChanged();
            int allCount = changes.Count;
            int succCount = 0;
            int failCount = 0;
            changes.ForEach((item) =>
            {
                if (item.UpdateModel())
                {
                    succCount++;
                }
                else
                {
                    failCount++;
                }
            });
            //若是全总更新成功，则重初始化未改变列
            if (allCount == succCount) { InitDataLoaded(); }
            return new Rule.EffectEntry { AllCount = allCount, SuccessCount = succCount, FailCount = failCount };
        }

    }
}
